
import Backfire
import unittest

def loadTestCssFile(uri):
    """Assumes uri matches css filepath"""
    return read_entire_file(uri)

def saveTestCssFile(uri, contents):
    """Assumes uri matches css filepath"""
    overwrite_text_to_file(uri, contents)
    
def overwrite_text_to_file(filename, contents):
    """ Overwrite <filename> with the string, <contents> """
    text_file = open(filename, "w")
    text_file.write(contents)
    text_file.close()
    
    
def read_entire_file(filename):
    """ Read all of <filename> and return as a string """
    try:
        text_file = open(filename, "r")
        whole_thing = text_file.read()
        text_file.close()
    except IOError as (errno, stderr):
        return ""

    return whole_thing


class TestBackfire(unittest.TestCase):

    test1css_before = """
body {
    background-color: white;
    width: 500px;
    font-family: Verdana;
    margin: 100px 100px;
}

.foo {
    font-family: Arial;
    color: red;
    font-size: 12px;
}

.bar {
    color: green;
    font-size: 16px;

    margin-left: 2px;
    padding: 10px 10px;
}

#object1 {
    margin: 0 0 10px 20px;
    color: red;

    font-size: 12px;
}
"""

    test_1_1_changes = """u:test.css
s:.foo
c:color:blue
"""

    testcss_1_1_after = """
body {
    background-color: white;
    width: 500px;
    font-family: Verdana;
    margin: 100px 100px;
}

.foo {
    font-family: Arial;
    color: blue;
    font-size: 12px;
}

.bar {
    color: green;
    font-size: 16px;

    margin-left: 2px;
    padding: 10px 10px;
}

#object1 {
    margin: 0 0 10px 20px;
    color: red;

    font-size: 12px;
}
"""

    test_1_2_changes = """u:test.css
s:.foo
c:color:blue
c:font-family:Courier
"""

    testcss_1_2_after = """
body {
    background-color: white;
    width: 500px;
    font-family: Verdana;
    margin: 100px 100px;
}

.foo {
    font-family: Courier;
    color: blue;
    font-size: 12px;
}

.bar {
    color: green;
    font-size: 16px;

    margin-left: 2px;
    padding: 10px 10px;
}

#object1 {
    margin: 0 0 10px 20px;
    color: red;

    font-size: 12px;
}
"""

    test_1_3_changes = """u:test.css
s:.foo
c:color:blue
c:font-family:Courier
s:.bar
c:color:red
c:margin-left:4px
c:font-size:12px
s:#object1
c:color:blue
c:margin:10px 0 10px 0
"""
   
    testcss_1_3_after = """
body {
    background-color: white;
    width: 500px;
    font-family: Verdana;
    margin: 100px 100px;
}

.foo {
    font-family: Courier;
    color: blue;
    font-size: 12px;
}

.bar {
    color: red;
    font-size: 12px;

    margin-left: 4px;
    padding: 10px 10px;
}

#object1 {
    margin: 10px 0 10px 0;
    color: blue;

    font-size: 12px;
}
"""
 
    test2css_before = """
body {
    background-color: white;
    width: 500px;
    font-family: Verdana;
    margin: 100px 100px;
}

.foo {
    font-family: Arial;
    color: red;
    font-size: 12px;
}

.bar {
    color: green;
    font-size: 16px;

    margin-left: 2px;
    padding: 10px 10px;
}

#object1 {
    margin: 0 0 10px 20px;
    color: red;

    font-size: 12px;
}
"""

    test_2_1_changes = """u:test.css
s:.foo
a:width:200px
"""
   
    testcss_2_1_after = """
body {
    background-color: white;
    width: 500px;
    font-family: Verdana;
    margin: 100px 100px;
}

.foo {
    font-family: Arial;
    color: red;
    font-size: 12px;
    width: 200px;
}

.bar {
    color: green;
    font-size: 16px;

    margin-left: 2px;
    padding: 10px 10px;
}

#object1 {
    margin: 0 0 10px 20px;
    color: red;

    font-size: 12px;
}
"""

    test_2_2_changes = """u:test.css
s:.foo
a:width:200px
a:height:300px
s:.bar
a:margin-right:3px
s:body
a:padding:10px 10px
"""
   
    testcss_2_2_after = """
body {
    background-color: white;
    width: 500px;
    font-family: Verdana;
    margin: 100px 100px;
    padding: 10px 10px;
}

.foo {
    font-family: Arial;
    color: red;
    font-size: 12px;
    width: 200px;
    height: 300px;
}

.bar {
    color: green;
    font-size: 16px;

    margin-left: 2px;
    padding: 10px 10px;
    margin-right: 3px;
}

#object1 {
    margin: 0 0 10px 20px;
    color: red;

    font-size: 12px;
}
"""

    test3css_before = """
body {
    background-color: white;
    width: 500px;
    font-family: Verdana;
    margin: 100px 100px;
}

.foo {
    font-family: Arial;
    color: red;
    font-size: 12px;
}

.bar {
    color: green;
    font-size: 16px;

    margin-left: 2px;
    padding: 10px 10px;
}

#object1 {
    margin: 0 0 10px 20px;
    color: red;

    font-size: 12px;
}
"""

    test_3_1_changes = """u:test.css
s:.foo
r:color:red
r:font-size:12px
s:.bar
r:color:green
s:body
r:width:500px
s:#object1
r:margin:0 0 10px 20px
r:font-size:12px
"""

    testcss_3_1_after = """
body {
    background-color: white;
    font-family: Verdana;
    margin: 100px 100px;
}

.foo {
    font-family: Arial;
}

.bar {
    font-size: 16px;

    margin-left: 2px;
    padding: 10px 10px;
}

#object1 {
    color: red;
}
"""

    test_3_2_changes = """u:test.css
s:.foo
r:margin:0 0 10px 10px
r:width:100px
r:color:green
r:font-size:14px
"""

    testcss_3_2_after = """
body {
    background-color: white;
    width: 500px;
    font-family: Verdana;
    margin: 100px 100px;
}

.foo {
    font-family: Arial;
    color: red;
    font-size: 12px;
}

.bar {
    color: green;
    font-size: 16px;

    margin-left: 2px;
    padding: 10px 10px;
}

#object1 {
    margin: 0 0 10px 20px;
    color: red;

    font-size: 12px;
}
"""

    test_4_1_changes = """u:does_not_exist.css
s:.foo
r:margin:0 0 10px 10px
"""

    test_5_1_changes = """u:permission_denied.css
s:.foo
r:margin:0 0 10px 10px
"""

    def setUp(self):
        pass

    def runBasicProcessTest(self, beforeCss, changes, afterCss):
        """Test a number of changes to existing css attributes"""
        overwrite_text_to_file("test.css", beforeCss)
        Backfire.process(changes, loadTestCssFile, saveTestCssFile)

        result = read_entire_file("test.css")
        self.assertEqual(result, afterCss,
                         "=== Should be:\n%s===Actual:\n%s" % (afterCss, result))

    def test_change(self):
        """Test a number of changes to existing css attributes"""

        self.runBasicProcessTest(self.test1css_before, self.test_1_1_changes, self.testcss_1_1_after)
        self.runBasicProcessTest(self.test1css_before, self.test_1_2_changes, self.testcss_1_2_after)
        self.runBasicProcessTest(self.test1css_before, self.test_1_3_changes, self.testcss_1_3_after)

    def test_add(self):
        """Test a number of additions to existing css selectors"""
        self.runBasicProcessTest(self.test1css_before, self.test_2_1_changes, self.testcss_2_1_after)
        self.runBasicProcessTest(self.test1css_before, self.test_2_2_changes, self.testcss_2_2_after)

    def test_remove(self):
        """Test a number of removals to existing css selectors"""
        self.runBasicProcessTest(self.test3css_before, self.test_3_1_changes, self.testcss_3_1_after)
        
        # Trying removing attributes that don't exist
        # Behavior right now is that it matches the attribute only, not the value
        # self.runBasicProcessTest(self.test3css_before, self.test_3_2_changes, self.testcss_3_2_after)

    def test_file_does_not_exist(self):
        self.assertTrue(
            Backfire.process(self.test_4_1_changes, loadTestCssFile, saveTestCssFile)==
            Backfire.LOAD_FAILED)

    def test_file_permission_fail(self):
        # Try to open a file that you don't have read permission to
        self.assertTrue(
            Backfire.process(self.test_5_1_changes, loadTestCssFile, saveTestCssFile)==
            Backfire.ACCESS_DENIED)

        # Try to write to a file you have read-only permissions to
        
    
        
    

if __name__ == '__main__':
    unittest.main()


